package data

import (
	"gitee.com/fowa/fowa-server/internal/biz"
	"github.com/pkg/errors"
	"gorm.io/gorm"
)

type taskData struct {
	db *gorm.DB
}

func NewTaskData(db *gorm.DB) *taskData {
	return &taskData{
		db: db,
	}
}

// table Custom table name
func (d *taskData) table() *gorm.DB {
	return d.db.Table("task")
}

func (d *taskData) query(cond *biz.TaskCondition) *gorm.DB {

	t := d.table()

	if cond.TaskName != "" {
		t = t.Where("task_name = ?", cond.TaskName)
	}

	if cond.ID != 0 {
		t = t.Where("id = ?", cond.ID)
	}

	return t
}

// Create task
func (d *taskData) Create(task *biz.Task) (*biz.Task, error) {
	if c := d.table().Create(task); c.Error != nil {
		return nil, errors.Wrap(c.Error, "task create failed")
	}
	return task, nil
}

func (d *taskData) Update(id uint, task *biz.TaskUpdate) (*biz.Task, error) {
	var (
		m      *biz.Task
		fields []interface{}
		doc    map[string]interface{}
	)

	t := d.table().Model(m)

	if task.TaskName != "" {
		fields = append(fields, "task_name")
		doc["task_name"] = task.TaskName
	}

	if task.EndTime != "" {
		fields = append(fields, "end_time")
		doc["end_time"] = task.EndTime
	}

	if task.StartTime != "" {
		fields = append(fields, "start_time")
		doc["start_time"] = task.StartTime
	}

	if task.Image != "" {
		fields = append(fields, "image")
		doc["image"] = task.Image
	}

	if task.Env != "" {
		fields = append(fields, "env")
		doc["env"] = task.Env
	}

	if task.Status != 0 {
		fields = append(fields, "status")
		doc["status"] = task.Status
	}

	if u := t.Where("id = ?", id).Select(fields[0], fields...).Updates(doc); u.Error != nil {
		return nil, errors.Wrap(u.Error, "task update failed")
	}

	return m, nil
}

func (d *taskData) List(cond *biz.TaskCondition) ([]*biz.Task, error) {
	var tasks []*biz.Task
	if f := d.query(cond).Find(&tasks); f.Error != nil {
		return nil, errors.Wrap(f.Error, "task select failed")
	}
	return tasks, nil
}

func (d *taskData) Find(cond *biz.TaskCondition) (*biz.Task, error) {
	task := &biz.Task{}
	if f := d.query(cond).First(&task); f.Error != nil {
		return nil, errors.Wrap(f.Error, "task find failed")
	}
	return task, nil
}

func (d *taskData) Exist(cond *biz.TaskCondition) bool {

	task, err := d.Find(cond)

	if err != nil {
		return false
	}

	if task.ID == 0 {
		return false
	}

	return true
}
